#ifndef FACTORY_H_
#define FACTORY_H_

/*
 *	<p>	Factory Pattern </p>
 *	@author:	Kenvi.Luo
 *	@email:		kenvi.luo@gmail.com
 *	@date:		2007/08/06
 *	@modify:	N/A
 *	----------------------------
 *	@samples:
 *		using namepsace OPENPATTERN::PATTERN;
 *		Product *product = SINGLETON(FACTORY(Product)).createProduct();
 *		SINGLETON(FACTORY(Product)).destroyProduct(product);
 */

#include "../stragy/allocater/DefaultAllocater.h"
#include "../stragy/allocater/PoolAllocater.h"
#include "../stragy/threadsafe/CriticalLock.h"
 
namespace FURY
{
	using STRAGY::DefaultAllocater;
	using STRAGY::PoolAllocater;
	using STRAGY::CriticalLock;

	namespace PATTERN
	{
		#define FACTORY(T)		Factory<T>

		template<typename Product, typename Lock = CriticalLock, int once_allocate_size = 4, int max_allocate_size = 128, 
			template<typename T = Product, typename L = Lock, int O = once_allocate_size, int M = max_allocate_size > class Allocater = DefaultAllocater>
		class Factory
		{
			Allocater<Product, Lock, once_allocate_size, max_allocate_size > m_allocater;
		public:
			Factory()
			{
			};

			Product* createProduct()
 			{
 				return m_allocater.allocate();
 			};
 			
			void destroyProduct(Product *product)
 			{
 				m_allocater.free(product);
 			};
		};
	};
};

#endif /*FACTORY_H_*/
